package LRUCache;

import java.util.HashMap;

/**
 * Description:
 * User:岁亮亮
 * Date:2025-03-25
 * TIME:9:01
 */
public class MyLRUCache {

    static class Node{
        int key;
        int val;
        Node next;
        Node prev;
        public Node(){

        }
        public Node(int key,int val){
            this.key = key;
            this.val = val;
        }
    }

    public Node head;//头节点表示最近最少使用的节点
    public Node tail;//尾巴节点表示最近常用的节点
    public int usedSize;
    public HashMap<Integer,Node> hashMap;
    public int capacity;


    public MyLRUCache(int capacity) {
        this.capacity = capacity;
        this.head = new Node();
        this.tail = new Node();
        hashMap = new HashMap<>();
        head.next = tail;
        tail.prev = head;
    }

    public int getUsedSize() {
        return usedSize;
    }
    public void put(int key,int val){
        //判断key 是否再hashmap中存储过
        //存储过 更新val  和  因为这也算一次最近访问 把这个节点移动至尾巴节点
        if(hashMap.containsKey(key) == true){
            //更新val
            if(hashMap.get(key).val != val){
                hashMap.get(key).val = val;
            }
            //移动该节点到尾巴节点
            Node node = hashMap.get(key);
            moveToTail(node);
        }
        else{
            //没有存储过, 首先判断当前容量是否指定的容量
            //超过删除头节点 没有超过在尾巴节点进行插入
            Node newNode = new Node(key,val);
            //在尾巴节点进行插入新节点
            insertTail(newNode);
            usedSize++;
            hashMap.put(key,newNode);
            if(getUsedSize() >= capacity){
                //删除头节点
                Node removeNode = head.next;
                if(removeNode.next != null){//或者 ta 不等于tail节点也可以
                    head.next = removeNode.next;
                    removeNode.next.prev = head;
                    hashMap.remove(removeNode.key);
                    usedSize--;
                }
            }

        }
    }

    private void moveToTail(Node node) {
        //删除该节点;
        romoveNode(node);
        //添加到尾巴节点
        insertTail(node);
    }

    private void romoveNode(Node node) {
        node.prev.next = node.next;
        node.next.prev = node.prev;
    }

    private void insertTail(Node newNode){
            if(newNode != null){
                Node prevNode = tail.prev;
                prevNode.next = newNode;
                newNode.prev = prevNode;
                newNode.next = tail;
                tail.prev = newNode;
            }


    }
    public int get(int key){
        Node node = hashMap.get(key);
        if(node == null){
            return -1;
        }
        moveToTail(node);
        return node.val;
    }
}
